// Copyright 2020 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

package kcidb

// Kernel CI report data. To be submitted to/queried from the common report database.
//
// Objects in the data are identified and linked together using "id" and "*_id" string properties.
// Each value of these properties must start with a non-empty string identifying the CI system which
// submitted the object, followed by a colon ':' character. The rest of the string is generated by
// the origin CI system, and must identify that object uniquely among all objects of the same type,
// coming from that CI system.
//
// Any of the immediate properties (except "version") can be missing or be an empty list with each
// submission/query, but only complete data stored in the database should be considered valid.
//
// E.g. a test run referring to a non-existent build is allowed into/from the database,
// but would only appear in reports once both the build and its revision are present.
//
// No special meaning apart from "data is missing" is attached to any immediate or deeper properties being omitted,
// when they're not required, and no default values should be assumed for them.
// At the same time, no properties can be null.
//
// Extra free-form data can be stored under "misc" fields associated with various objects throughout the schema,
// if necessary. That data could later be used as the basis for defining new properties to house it.
type Kcidb struct {
	Checkouts []*Checkout `json:"checkouts,omitempty"`
	Builds    []*Build    `json:"builds,omitempty"`
	Tests     []*Test     `json:"tests,omitempty"`
	Issues    []*Issue    `json:"issues,omitempty"`
	Incidents []*Incident `json:"incidents,omitempty"`
	Version   *Version    `json:"version"`
}

// A build of a checkout.
type Build struct {
	// The last time the build was updated in the database.
	Timestamp string `json:"_timestamp,omitempty"`

	// ID of the built source code checkout. The checkout must be valid for the build to be considered valid.
	CheckoutID string `json:"checkout_id"`

	// Build ID.
	// Must start with a non-empty string identifying the CI system which submitted the build,
	// followed by a colon ':' character. The rest of the string is generated by the origin CI system,
	// and must identify the build uniquely among all builds, coming from that CI system.
	ID string `json:"id"`

	// The name of the CI system which submitted the build.
	Origin string `json:"origin"`

	// A human-readable comment regarding the build.
	Comment string `json:"comment,omitempty"`

	// The time the build was started.
	StartTime string `json:"start_time,omitempty"`

	// The number of seconds it took to complete the build.
	Duration float64 `json:"duration,omitempty"`

	// Target architecture of the build.
	Architecture string `json:"architecture,omitempty"`

	// Full shell command line used to make the build, including environment variables.
	Command string `json:"command,omitempty"`

	// Name and version of the compiler used to make the build.
	Compiler string `json:"compiler,omitempty"`

	// A list of build input files. E.g. configuration.
	InputFiles []*Resource `json:"input_files,omitempty"`

	// A list of build output files: images, packages, etc.
	OutputFiles []*Resource `json:"output_files,omitempty"`

	// A name describing the build configuration options.
	ConfigName string `json:"config_name,omitempty"`

	// The URL of the build configuration file.
	ConfigURL string `json:"config_url,omitempty"`

	// The URL of the plain-text build log file.
	LogURL string `json:"log_url,omitempty"`

	// A part of the build log most relevant to its outcome.
	LogExcerpt string `json:"log_excerpt,omitempty"`

	// Build status: FAIL, ERROR, MISS, PASS, DONE, or SKIP.
	Status string `json:"status,omitempty"`

	// Miscellaneous extra data about the build.
	Misc *BuildMisc `json:"misc,omitempty"`
}

// Miscellaneous extra data about the build.
type BuildMisc struct {
	OriginURL  string `json:"origin_url,omitempty"`
	ReportedBy string `json:"reported_by,omitempty"`
}

// The environment the test ran in. E.g. a host, a set of hosts, or a lab;
// amount of memory/storage/CPUs, for each host; process environment variables, etc.
type Environment struct {
	// The values from the root-level 'compatible' property of the system's device tree.
	Compatible []string `json:"compatible,omitempty"`

	// Human-readable comment of the environment.
	Comment string `json:"comment,omitempty"`

	// Miscellaneous extra data about the environment.
	Misc *EnvironmentMisc `json:"misc,omitempty"`
}

// Miscellaneous extra data about the environment.
type EnvironmentMisc struct {
}

// A checkout of the tested code.
//
// Represents a way the tested source code could be obtained. E.g. checking out a particular commit from a git repo,
// and applying a set of patches on top.
type Checkout struct {
	// The last time the checkout was updated in the database.
	Timestamp string `json:"_timestamp,omitempty"`

	// Source code checkout ID.
	// Must start with a non-empty string identifying the CI system which submitted the checkout,
	// followed by a colon ':' character. The rest of the string is generated by the origin CI system,
	// and must identify the checkout uniquely among all checkouts, coming from that CI system.
	ID string `json:"id"`

	// The name of the CI system which submitted the checkout.
	Origin string `json:"origin"`

	// The widely-recognized name of the sub-tree (fork) of the main code tree where the checked out
	// base source code came from.
	TreeName string `json:"tree_name,omitempty"`

	// The URL of the Git repository which contains the base code of the checkout. The shortest possible https:// URL.
	GitRepositoryURL string `json:"git_repository_url,omitempty"`

	// The full commit hash of the checked out base source code.
	GitCommitHash string `json:"git_commit_hash,omitempty"`

	// A human-readable name of the commit containing the checked out base source code, as would be
	// output by "git describe", at the checkout time.
	GitCommitName string `json:"git_commit_name,omitempty"`

	// The list of (annotated) tags, found in the repository, pointing directly at the checked out commit.
	GitCommitTags []string `json:"git_commit_tags,omitempty"`

	// The complete message of the commit being checked out, both the subject and the body.
	GitCommitMessage string `json:"git_commit_message,omitempty"`

	// The Git repository branch from which the commit with the base source code was checked out.
	GitRepositoryBranch string `json:"git_repository_branch,omitempty"`

	// Whether the checked out commit was at the tip of the specified branch at checkout time.
	GitRepositoryBranchTip bool `json:"git_repository_branch_tip,omitempty"`

	// List of patch files applied to the checked out base source code, in order of application.
	PatchsetFiles []*Resource `json:"patchset_files,omitempty"`

	// The patchset hash. Empty if no patches were applied.
	PatchsetHash string `json:"patchset_hash,omitempty"`

	// The value of the Message-ID header of the e-mail message introducing the checkout, if any.
	MessageID string `json:"message_id,omitempty"`

	// A human-readable comment regarding the checkout. E.g. the checked out release version.
	Comment string `json:"comment,omitempty"`

	// The time the checkout was started.
	StartTime string `json:"start_time,omitempty"`

	// The time the checkout origin finished all planned builds for it.
	OriginBuildsFinishTime string `json:"origin_builds_finish_time,omitempty"`

	// The time the checkout origin finished all planned tests for it.
	OriginTestsFinishTime string `json:"origin_tests_finish_time,omitempty"`

	// The URL of a plain-text log file of the checkout attempt. E.g. 'git am' output.
	LogURL string `json:"log_url,omitempty"`

	// A part of the checkout log most relevant to its outcome.
	LogExcerpt string `json:"log_excerpt,omitempty"`

	// True if the checkout succeeded, i.e. if the source code parts could be combined.
	// False if not, e.g. if the patches failed to apply.
	Valid bool `json:"valid,omitempty"`

	// Miscellaneous extra data about the checkout.
	Misc *CheckoutMisc `json:"misc,omitempty"`
}

// Miscellaneous extra data about the checkout.
type CheckoutMisc struct {
}

// A test run against a build.
//
// Could represent a result of execution of a test suite program, a result of one of the tests done by the test
// suite program, as well as a summary of a collection of test suite results.
//
// Each test run should normally have a dot-separated test "path" specified in the "path" property,
// which could identify a specific test within a test suite (e.g. "LTPlite.sem01"), a whole test suite
// (e.g. "LTPlite"), or the summary of all tests for a build ( - the empty string).
type Test struct {
	// The last time the test was updated in the database.
	Timestamp string `json:"_timestamp,omitempty"`

	// ID of the tested build. The build must be valid for the test run to be considered valid.
	BuildID string `json:"build_id"`

	// ID of the test run.
	// Must start with a non-empty string identifying the CI system which submitted the test run,
	// followed by a colon ':' character. The rest of the string is generated by the origin CI system,
	// and must identify the test run uniquely among all test runs, coming from that CI system.
	ID string `json:"id"`

	// The name of the CI system which submitted the test run.
	Origin string `json:"origin"`

	// The environment the test ran in. E.g. a host, a set of hosts, or a lab; amount of memory/storage/CPUs,
	// for each host; process environment variables, etc.
	Environment *Environment `json:"environment,omitempty"`

	// Dot-separated path to the node in the test classification tree the executed test belongs to.
	// E.g. "ltp.sem01". The empty string signifies the root of the tree, i.e. all tests for the build,
	// executed by the origin CI system.
	Path string `json:"path,omitempty"`

	// A human-readable comment regarding the test run.
	Comment string `json:"comment,omitempty"`

	// The URL of the plain-text test output or log file. If multiple outputs exist, this should point to the
	// highest-level overview of the test's operation. The rest should go into output_files.
	LogURL string `json:"log_url,omitempty"`

	// A part of the test log most relevant to the test outcome.
	LogExcerpt string `json:"log_excerpt,omitempty"`

	// The test status string: FAIL, ERROR, MISS, PASS, DONE, or SKIP.
	Status string `json:"status,omitempty"`

	// The numerical output produced by the test, if any.
	Number *TestNumber `json:"number,omitempty"`

	// The time the test run was started.
	StartTime string `json:"start_time,omitempty"`

	// The number of seconds it took to run the test.
	Duration float64 `json:"duration,omitempty"`

	// Test input files (rootfs, initramfs, etc.).
	InputFiles []*Resource `json:"input_files,omitempty"`

	// A list of test outputs: logs, dumps, etc. Except the file referenced by log_url.
	OutputFiles []*Resource `json:"output_files,omitempty"`

	// Miscellaneous extra data about the test run.
	Misc *TestMisc `json:"misc,omitempty"`
}

// The numerical output produced by a test run.
type TestNumber struct {
	// The floating-point output value.
	Value float64 `json:"value"`

	// The (compound) unit symbols the value is measured in.
	Unit string `json:"unit,omitempty"`

	// The type of prefix to add to the unit when displaying the value: "metric" or "binary".
	Prefix string `json:"prefix,omitempty"`
}

// Miscellaneous extra data about the test.
type TestMisc struct {
	OriginURL       string `json:"origin_url,omitempty"`
	ReportedBy      string `json:"reported_by,omitempty"`
	UserSpaceArch   string `json:"user_space_arch,omitempty"`
	CauseRevisionID string `json:"cause_revision_id,omitempty"`
}

// A named remote resource.
type Resource struct {
	// Resource name. Must be usable as a local file name for the downloaded resource. Cannot be empty.
	// Should not include directories.
	Name string `json:"name"`

	// Resource URL. Must point to the resource file directly, so it could be downloaded automatically.
	URL string `json:"url"`
}

type Version struct {
	// Major number of the schema version.
	//
	// Increases represent backward-incompatible changes. E.g. deleting or renaming a property,
	// changing a property type, restricting values, making a property required, or adding a new required property.
	Major int `json:"major"`

	// Minor number of the schema version.
	//
	// Increases represent backward-compatible changes. E.g. relaxing value restrictions,
	// making a property optional, or adding a new optional property.
	Minor int `json:"minor,omitempty"`
}

// An issue found in reports.
type Issue struct {
	// The last time the issue was updated in the database.
	Timestamp string `json:"_timestamp,omitempty"`

	// Issue ID.
	// Must start with a non-empty string identifying the CI system which submitted the issue,
	// followed by a colon ':' character. The rest of the string is generated by the origin CI system,
	// and must identify the issue uniquely among all issues, coming from that CI system.
	ID string `json:"id"`

	// The modification version number of the issue. Only the highest-numbered version is used for triaging.
	Version int `json:"version"`

	// The name of the CI system which submitted the issue.
	Origin string `json:"origin"`

	// Dot-separated paths pointing to nodes in the categorization tree the issue belongs to.
	Categories []string `json:"categories,omitempty"`

	// The URL of a report describing the issue.
	ReportURL string `json:"report_url,omitempty"`

	// The subject of the report describing the issue.
	ReportSubject string `json:"report_subject,omitempty"`

	// Layers of the execution stack responsible for the issue. If all are false, the issue is considered invalid.
	Culprit *IssueCulprit `json:"culprit,omitempty"`

	// A human-readable comment regarding the issue. E.g. a brief description, or a report subject.
	Comment string `json:"comment,omitempty"`

	// Miscellaneous extra data about the issue.
	Misc *IssueMisc `json:"misc,omitempty"`
}

// The layers responsible for an issue.
type IssueCulprit struct {
	// The built/tested code.
	Code bool `json:"code,omitempty"`

	// The tool - the static analyzer, the build toolchain, the test, etc.
	Tool bool `json:"tool,omitempty"`

	// The harness - the system controlling the execution of the build/test.
	Harness bool `json:"harness,omitempty"`
}

// Miscellaneous extra data about the issue.
type IssueMisc struct {
}

// An incident - an issue occurrence/absence.
type Incident struct {
	// The last time the incident was updated in the database.
	Timestamp string `json:"_timestamp,omitempty"`

	// Incident ID.
	// Must start with a non-empty string identifying the CI system which submitted the incident,
	// followed by a colon ':' character. The rest of the string is generated by the origin CI system,
	// and must identify the incident uniquely among all incidents, coming from that CI system.
	ID string `json:"id"`

	// The name of the CI system which submitted the incident.
	Origin string `json:"origin"`

	// The ID of the occurring/absent issue.
	IssueID string `json:"issue_id"`

	// The modification version number of the occurring/absent issue.
	IssueVersion int `json:"issue_version"`

	// The ID of the build object exhibiting/missing the issue.
	BuildID string `json:"build_id,omitempty"`

	// The ID of the test object exhibiting/missing the issue.
	TestID string `json:"test_id,omitempty"`

	// True if the issue occurred in the linked objects. False if it was absent.
	Present bool `json:"present,omitempty"`

	// A human-readable comment regarding the incident.
	Comment string `json:"comment,omitempty"`

	// Miscellaneous extra data about the incident.
	Misc *IncidentMisc `json:"misc,omitempty"`
}

// Miscellaneous extra data about the incident.
type IncidentMisc struct {
}
